package com.example.springbootlucenedemo.common.lucene.conf;

import com.example.springbootlucenedemo.common.lucene.impl.MessageReceiver;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.*;

import java.util.concurrent.*;

@Configuration
public class RedisConf {
    @Autowired(required = false)
    MessageReceiver messageReceiver;


    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.setValueSerializer( new GenericJackson2JsonRedisSerializer());
            redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     *
     * @param redisConnectionFactory
     * @param addDocument
     * @param deleteDocument
     * @param updateDocument
     * @return
     */
    @Bean
    @ConditionalOnProperty(name="spring.lucene.pub/subModel",havingValue="true",matchIfMissing = false)
    public RedisMessageListenerContainer container (RedisConnectionFactory redisConnectionFactory,
                                                    MessageListenerAdapter addDocument,
                                                    MessageListenerAdapter deleteDocument,
                                                    MessageListenerAdapter updateDocument){
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
            redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
            redisMessageListenerContainer.addMessageListener(addDocument,new PatternTopic(RedisMessageTopic.addDocument));
            redisMessageListenerContainer.addMessageListener(deleteDocument,new PatternTopic(RedisMessageTopic.deleteDocument));
            redisMessageListenerContainer.addMessageListener(updateDocument,new PatternTopic(RedisMessageTopic.updateDocument));
            // 自定义线程池,防止oom
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            redisMessageListenerContainer.setTaskExecutor(executorService);
        return redisMessageListenerContainer;
    }

    @Bean
    @ConditionalOnProperty(name="spring.lucene.pub/subModel",havingValue="true",matchIfMissing = false)
    public MessageListenerAdapter addDocument(){
        return new MessageListenerAdapter(messageReceiver, RedisMessageDefaultListenerMethod.addDocument);
    }
    @Bean
    @ConditionalOnProperty(name="spring.lucene.pub/subModel",havingValue="true",matchIfMissing = false)
    public MessageListenerAdapter deleteDocument(){
        return new MessageListenerAdapter(messageReceiver, RedisMessageDefaultListenerMethod.deleteDocument);
    }
    @Bean
    @ConditionalOnProperty(name="spring.lucene.pub/subModel",havingValue="true",matchIfMissing = false)
    public MessageListenerAdapter updateDocument(){
        return new MessageListenerAdapter(messageReceiver, RedisMessageDefaultListenerMethod.updateDocument);
    }

    public static final class RedisMessageTopic {
        public static final String addDocument = "queue:addDocument";
        public static final String deleteDocument = "queue:deleteDocument";
        public static final String updateDocument = "queue:updateDocument";
    }

    public static final class RedisMessageDefaultListenerMethod {
        public static final String addDocument = "addDocument";
        public static final String deleteDocument = "deleteDocument";
        public static final String updateDocument = "updateDocument";
    }
}
